﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Forms;


namespace ZTZP_BEMSS_WPF
{
    /// <summary>
    /// 管理不同基准价下的公司排名和分数信息
    /// </summary>
    public class RankList
    {
        /// <summary>
        /// 存储排名信息的嵌套字典
        /// 外层键：BasePriceEntry（基准价条目）
        /// 内层键：公司名称
        /// 值：包含排名和分数的元组
        /// </summary>
        public Dictionary<BasePriceEntry, Dictionary<string, (int Rank, double Score)>> _RankDic;

        /// <summary>
        /// 构造函数，初始化排名字典
        /// </summary>
        public RankList()
        {
            _RankDic = new Dictionary<BasePriceEntry, Dictionary<string, (int Rank, double Score)>>();
        }

        /// <summary>
        /// 为特定基准价条目添加公司排名和分数
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <param name="companyName">公司名称</param>
        /// <param name="rank">公司排名</param>
        /// <param name="score">公司得分</param>
        public void AddRanking(BasePriceEntry basePrice, string companyName, int rank, double score)
        {
            // 如果该基准价条目不存在，创建新的字典
            if (!_RankDic.ContainsKey(basePrice))
            {
                _RankDic[basePrice] = new Dictionary<string, (int Rank, double Score)>();
            }

            // 添加或更新公司的排名和分数
            _RankDic[basePrice][companyName] = (rank, score);
        }

        /// <summary>
        /// 获取特定基准价条目下的所有公司排名和分数
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <returns>公司名称与排名分数对应的字典</returns>
        public Dictionary<string, (int Rank, double Score)> GetRankings(BasePriceEntry basePrice)
        {
            // 使用TryGetValue安全获取排名信息，如果不存在则返回空字典
            return _RankDic.TryGetValue(basePrice, out var rankings)
                ? new Dictionary<string, (int Rank, double Score)>(rankings)
                : new Dictionary<string, (int Rank, double Score)>();
        }

        /// <summary>
        /// 获取特定基准价条目下特定公司的排名和分数
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <param name="companyName">公司名称</param>
        /// <returns>包含排名和分数的元组，如果不存在则返回(-1, -1.0)</returns>
        public (int Rank, double Score) GetCompanyRankAndScore(BasePriceEntry basePrice, string companyName)
        {
            if (_RankDic.TryGetValue(basePrice, out var rankings))
            {
                // 尝试获取公司的排名信息，不存在则返回默认值
                return rankings.TryGetValue(companyName, out var rankInfo)
                    ? rankInfo
                    : (-1, -1.0);
            }
            return (-1, -1.0);
        }
        /// <summary>
        /// 获取特定公司在特定排名出现的次数和对应的基准价条目详情
        /// </summary>
        /// <param name="companyName">公司名称</param>
        /// <param name="rank">查询的排名</param>
        /// <returns>包含出现次数和基准价条目列表的元组</returns>
        public (int Count, List<BasePriceEntry> BasePriceEntries) GetCompanyRankOccurrences(string companyName, int rank)
        {
            // 查找所有具有指定公司和排名的基准价条目
            var matchingEntries = _RankDic
                .Where(entry =>
                    entry.Value.TryGetValue(companyName, out var rankInfo) &&
                    rankInfo.Rank == rank)
                .Select(entry => entry.Key)
                .ToList();

            // 返回出现次数和对应的基准价条目列表
            return (matchingEntries.Count, matchingEntries);
        }
        /// <summary>
        /// 获取所有唯一的公司名称
        /// </summary>
        /// <returns>包含所有公司名称的哈希集合</returns>
        public HashSet<string> GetAllCompanies()
        {
            // 使用 HashSet 确保公司名称唯一
            var companies = new HashSet<string>();

            // 遍历每个基准价条目的公司字典
            foreach (var basePriceEntry in _RankDic)
            {
                // 将当前基准价条目下的所有公司名称添加到集合中
                companies.UnionWith(basePriceEntry.Value.Keys);
            }

            return companies;
        }
        /// <summary>
        /// 获取特定基准价条目下排名最高的公司
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <returns>排名最高的公司名称，如果不存在则返回null</returns>
        public string GetTopRankedCompany(BasePriceEntry basePrice)
        {
            if (_RankDic.TryGetValue(basePrice, out var rankings))
            {
                // 按排名升序排序，返回第一个公司名称
                return rankings.OrderBy(x => x.Value.Rank).FirstOrDefault().Key;
            }
            return null;
        }

        /// <summary>
        /// 获取所有基准价条目的排名和分数信息
        /// </summary>
        /// <returns>完整的排名信息字典</returns>
        public Dictionary<BasePriceEntry, Dictionary<string, (int Rank, double Score)>> GetAllRankings()
        {
            return new Dictionary<BasePriceEntry, Dictionary<string, (int Rank, double Score)>>(_RankDic);
        }

        /// <summary>
        /// 删除特定基准价条目的所有排名信息
        /// </summary>
        /// <param name="basePrice">要删除排名的基准价条目</param>
        public void RemoveBasePriceRankings(BasePriceEntry basePrice)
        {
            _RankDic.Remove(basePrice);
        }

        /// <summary>
        /// 删除特定基准价条目下特定公司的排名
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <param name="companyName">公司名称</param>
        public void RemoveCompanyRanking(BasePriceEntry basePrice, string companyName)
        {
            if (_RankDic.TryGetValue(basePrice, out var rankings))
            {
                rankings.Remove(companyName);
            }
        }

        /// <summary>
        /// 检查是否存在特定基准价条目的排名信息
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <returns>是否存在该基准价条目的排名信息</returns>
        public bool HasBasePrice(BasePriceEntry basePrice)
        {
            return _RankDic.ContainsKey(basePrice);
        }

        /// <summary>
        /// 获取特定基准价条目下特定排名的所有公司
        /// </summary>
        /// <param name="basePrice">基准价条目</param>
        /// <param name="rank">排名</param>
        /// <returns>具有指定排名的公司列表</returns>
        public List<string> GetCompaniesByRank(BasePriceEntry basePrice, int rank)
        {
            if (_RankDic.TryGetValue(basePrice, out var rankings))
            {
                return rankings
                    .Where(x => x.Value.Rank == rank)
                    .Select(x => x.Key)
                    .ToList();
            }
            return new List<string>();
        }

        /// <summary>
        /// 获取特定公司在特定排名出现的所有基准价条目
        /// </summary>
        /// <param name="companyName">公司名称</param>
        /// <param name="rank">排名</param>
        /// <returns>该公司在指定排名的所有基准价条目</returns>
        public List<BasePriceEntry> GetBasePriceEntriesForCompanyRank(string companyName, int rank)
        {
            return _RankDic
                .Where(entry =>
                    entry.Value.TryGetValue(companyName, out var rankInfo) &&
                    rankInfo.Rank == rank)
                .Select(entry => entry.Key)
                .ToList();
        }

        /// <summary>
        /// 生成排名信息的详细文本描述
        /// </summary>
        /// <returns>包含所有基准价条目排名信息的字符串</returns>
        public string GetRankingsInfo()
        {
            StringBuilder message = new StringBuilder();

            // 用于统计各公司排名第一的次数
            var topRankCompanies = new Dictionary<string, int>();
            var topRankBasePriceEntries = new Dictionary<string, List<BasePriceEntry>>();

            foreach (var entry in _RankDic)
            {
                var basePriceEntry = entry.Key;
                var rankings = entry.Value;

                // 添加基准价条目的详细信息
                message.AppendLine($"基本参数: 下浮率={basePriceEntry.FloatingRate}, 下浮系数={basePriceEntry.FloatingK}, BValue={basePriceEntry.BValue}, BasePrice={basePriceEntry.BasePrice}");
                message.AppendLine("排名信息:");

                // 遍历每个公司的排名和分数
                foreach (var rank in rankings)
                {
                    message.AppendLine($"公司名称: {rank.Key}, 排名: {rank.Value.Rank}, 得分: {rank.Value.Score:F2}");

                    // 统计排名第一的公司
                    if (rank.Value.Rank == 1)
                    {
                        // 统计第一名出现的次数
                        if (!topRankCompanies.ContainsKey(rank.Key))
                        {
                            topRankCompanies[rank.Key] = 0;
                            topRankBasePriceEntries[rank.Key] = new List<BasePriceEntry>();
                        }
                        topRankCompanies[rank.Key]++;
                        topRankBasePriceEntries[rank.Key].Add(basePriceEntry);
                    }
                }

                // 添加空行分隔不同的基准价条目
                message.AppendLine();
            }

            // 添加排名第一的公司统计信息
            message.AppendLine("各公司排名第一的统计：");
            foreach (var company in topRankCompanies.OrderByDescending(x => x.Value))
            {
                message.AppendLine($"公司名称: {company.Key}, 排名第一次数: {company.Value}");
                message.AppendLine("对应的基准价条目：");
                foreach (var basePriceEntry in topRankBasePriceEntries[company.Key])
                {
                    message.AppendLine($"  下浮率={basePriceEntry.FloatingRate},下浮系数={basePriceEntry.FloatingK}, 评标基准价={basePriceEntry.BasePrice}");
                }
                message.AppendLine();
            }

            return message.ToString();
        }
    }

    /// <summary>
    /// 排名计算器，用于计算不同基准价条目下的公司排名
    /// </summary>
    public static class RankingCalculator
    {
        // 存储基准价条目集合
        private static ObservableCollection<BasePriceEntry> _BasePriceEntries;
        // 存储投标报价集合
        private static ObservableCollection<BidQuote> _BidQuotes;//所有公司的投标报价
        // 排名列表实例
        private static RankList _Ranklist = new RankList();

        /// <summary>
        /// 初始化排名计算器
        /// </summary>
        /// <param name="basePriceEntries">基准价条目集合</param>
        /// <param name="bidQuotes">投标报价集合</param>
        public static void Initialize(ObservableCollection<BasePriceEntry> basePriceEntries, ObservableCollection<BidQuote> bidQuotes)
        {
            _BasePriceEntries = basePriceEntries;
            _BidQuotes = bidQuotes;

            // 确保排名列表不为空
            if (_Ranklist == null)
                _Ranklist = new RankList();
        }

        /// <summary>
        /// 计算所有基准价条目下的公司排名
        /// </summary>
        public static void CalculateRankings()
        {
            // 检查是否已初始化基准价条目和投标报价
            if (_BasePriceEntries == null || _BidQuotes == null)
                throw new InvalidOperationException("Base price entries and bid quotes must be initialized first.");

            // 遍历每个基准价条目
            foreach (var basePriceEntry in _BasePriceEntries)
            {
                // 存储每个公司的分数
                var scores = new Dictionary<string, (double Score, double OriginalScore)>();
                foreach (var bidQuote in _BidQuotes)
                {
                    // 计算每个投标报价的分数
                    double score = CalculateScore(basePriceEntry.BasePrice, bidQuote.BidPrice);
                    scores[bidQuote.BidCompany] = (score, score);
                }

                // 按分数降序排序，分数相同时按公司名称排序
                var rankedCompanies = scores.OrderByDescending(x => x.Value.Score).ThenBy(x => x.Key).ToList();

                // 创建排名字典
                var rankDic = new Dictionary<string, (int Rank, double Score)>();
                for (int i = 0; i < rankedCompanies.Count; i++)
                {
                    // 排名从1开始
                    rankDic[rankedCompanies[i].Key] = (i + 1, rankedCompanies[i].Value.OriginalScore);
                }

                // 将排名信息存储到排名列表中
                _Ranklist._RankDic[basePriceEntry] = rankDic;
            }
        }

        /// <summary>
        /// 根据基准价和投标价计算分数
        /// </summary>
        /// <param name="basePrice">基准价</param>
        /// <param name="bidPrice">投标价</param>
        /// <returns>计算得到的分数</returns>
        private static double CalculateScore(double basePrice, double bidPrice)
        {
            // 如果投标价等于基准价，返回满分
            if (bidPrice == basePrice) return 100.0;

            // 计算价格偏离度
            double deviation = (bidPrice - basePrice) / basePrice;
            double score = 100.0;

            // 根据偏离方向和程度扣分
            if (deviation < 0)
            {
                // 低于基准价，较轻微扣分
                score -= Math.Abs(deviation) * 0.6;
            }
            else if (deviation > 0)
            {
                // 高于基准价，严重扣分
                score -= Math.Abs(deviation) * 0.9;
            }

            // 确保分数不为负
            return Math.Max(score, 0.0);
        }

        /// <summary>
        /// 获取当前的排名列表
        /// </summary>
        /// <returns>排名列表实例</returns>
        public static RankList GetRankList()
        {
            return _Ranklist;
        }




    }

    /// <summary>
    /// RangeNumDialog05.xaml 的交互逻辑
    /// </summary>
    public partial class RangeNumDialog05 : Window ,INotifyPropertyChanged
    {
        // 静态字段保存唯一实例
        private static RangeNumDialog05 _instance;
        private ObservableCollection<BasePriceEntry> _BasePriceEntries;//存储计算结果：B、Δ、K和评标基准价
        private ObservableCollection<BidQuote> _BidQuotes;//各个单位的投标报价
        private RankList _Ranklist;//排名
        private int _CompanyRangeNum;//参加投标的单位个数
        // INotifyPropertyChanged 实现
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        // 私有构造函数，确保只能通过 Instance 获取实例
        private RangeNumDialog05()
        {
            InitializeComponent();
            this.DataContext = this;
        }
        // 处理TextBox文本变化事件，确保不会超过RangeNum
        private void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        {
            var textBox = sender as System.Windows.Controls.TextBox;
            if (textBox != null)
            {
                // 获取文本框中的值，并确保它不超过 RangeNum
                if (int.TryParse(textBox.Text, out int newValue))
                {
                    if (newValue > RangeNum)
                    {
                        // 如果值超过 RangeNum，则设置为最大值
                        textBox.Text = RangeNum.ToString();
                    }
                }
            }
        }
        public int RangeNum//企业排名的数量，默认为最大企业的数量
        {
           
            get { return _CompanyRangeNum; }
            set
            {
                _CompanyRangeNum = value;
                OnPropertyChanged(nameof(RangeNum)); // 通知属性发生变化
            }
        }
  
       public void SetCompanyBidQuotesAndBidPrices(ObservableCollection<BidQuote>  BidQuotes, ObservableCollection<BasePriceEntry>  BasePriceEntries)
        {
            _BidQuotes = BidQuotes;
            _BasePriceEntries = BasePriceEntries;
            RangeNum = _BidQuotes.Count;//设置之后文本框会自动变化

        }

        // 提供对单例实例的访问
        public static RangeNumDialog05 Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new RangeNumDialog05();
                }
                return _instance;
            }
        }

        // 上一步 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // 获取 BasePriceCalRes04 的单例实例
            BasePriceCalRes04 BPCR04 = BasePriceCalRes04.Instance;

            // 如果窗口没有显示，则显示它
            if (!BPCR04.IsVisible)
            {
                BPCR04.Left = this.Left + (this.Width - BPCR04.Width) / 2;
                BPCR04.Top = this.Top + (this.Height - BPCR04.Height) / 2;
                BPCR04.Show();
            }

            // 关闭当前窗口
            this.Hide();
        }
        //排名，下一步
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            #region 1 //计算不同BasePriceEntry情况下，公司的排名
            RankingCalculator.Initialize(_BasePriceEntries, _BidQuotes);
            RankingCalculator.CalculateRankings();
            RankList rankList = RankingCalculator.GetRankList();
            string message = rankList.GetRankingsInfo();
            #endregion 1

            #region 2 输出不同系数下得排名
            Form_Messagebox messagebox = new Form_Messagebox();
            messagebox.Title = "不同参数下的排名信息";
            messagebox.SetMessage(message);
            // 最终输出统计结果
            messagebox.ShowDialog();//模态对话框
            #endregion 2
           
            #region 3 弹出显示对话框
            // 获取 SummaryResDialog06 的单例实例
            SummaryResDialog06 SRD06 = SummaryResDialog06.Instance;
            SRD06.SetRankList(rankList);
            SRD06.SetBidQuotes(_BidQuotes);
            // 如果窗口没有显示，则显示它
            if (!SRD06.IsVisible)
            {
                SRD06.Left = this.Left + (this.Width - SRD06.Width) / 2;
                SRD06.Top = this.Top + (this.Height - SRD06.Height) / 2;
                SRD06.Show();
            }
            #endregion 3 
            

            #region 4 隐藏当前的对话框
            // 关闭当前窗口
            this.Hide();
            #endregion 4 
            #region 3 弹出显示对话框
            /***
           // 获取 SummaryResDialog06 的单例实例
           RedHeartBeatingDialog07 RBD07 = RedHeartBeatingDialog07.Instance;

           // 如果窗口没有显示，则显示它
           if (!RBD07.IsVisible)
           {
               RBD07.Left = this.Left + (this.Width - RBD07.Width) / 2;
               RBD07.Top = this.Top + (this.Height - RBD07.Height) / 2;
               RedHeartBeatingDialog07.ShowDialogOnce();  // 在任意地方调用
           }
           ***/
            #endregion 3 



        }
    }
}
